package io.task.cc.message.socket.thread.pool;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;


public class DefaultThreadFactory implements ThreadFactory {

    /**
     * The cacheMap of name and thread factory.
     */
    private static final Map<String, DefaultThreadFactory> mapOfNameAndThreadFactory = new HashMap<>();

    /**
     * The cacheMap of name and atomic integer.
     */
    private static final Map<String, AtomicInteger> mapOfNameAndAtomicInteger = new HashMap<>();

    public static DefaultThreadFactory getInstance(String threadName) {
        return getInstance(threadName, Thread.NORM_PRIORITY);
    }

    /**
     * Gets the single INSTANCE of DefaultThreadFactory.
     *
     * @param threadName the thread name
     * @param priority   the priority
     * @return single INSTANCE of DefaultThreadFactory
     */
    public static DefaultThreadFactory getInstance(String threadName, Integer priority) {
        DefaultThreadFactory defaultThreadFactory = mapOfNameAndThreadFactory.get(threadName);
        if (defaultThreadFactory == null) {
            defaultThreadFactory = new DefaultThreadFactory();
            if (priority != null) {
                defaultThreadFactory.priority = priority;
            }

            defaultThreadFactory.setThreadName(threadName);
            mapOfNameAndThreadFactory.put(threadName, defaultThreadFactory);
            mapOfNameAndAtomicInteger.put(threadName, new AtomicInteger());
        }
        return defaultThreadFactory;
    }


    private String threadPoolName = null;


    private int priority = Thread.NORM_PRIORITY;


    private DefaultThreadFactory() {

    }


    public String getThreadPoolName() {
        return threadPoolName;
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setName(this.getThreadPoolName() + "-" + mapOfNameAndAtomicInteger.get(this.getThreadPoolName()).incrementAndGet());
        thread.setPriority(priority);
        return thread;
    }

    /**
     * Sets the thread name.
     */
    public void setThreadName(String threadName) {
        this.threadPoolName = threadName;
    }

}
